package service

import (
	"encoding/json"

	"github.com/AsynkronIT/protoactor-go/actor"

	nactor "nggs/actor"
	nexport "nggs/export"
)

const (
	NilPayload = -1
)

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
type InstanceExtra map[string]interface{}

func (e *InstanceExtra) Clone() *InstanceExtra {
	if e == nil {
		return nil
	}
	n := &InstanceExtra{}
	for k, v := range *e {
		(*n)[k] = v
	}
	return n
}

func (e InstanceExtra) Get(key string) (value interface{}, ok bool) {
	value, ok = e[key]
	return
}

func (e *InstanceExtra) Set(key string, value interface{}) {
	(*e)[key] = value
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
type Instance struct {
	PID          *actor.PID
	PprofAddress string
	Extra        *InstanceExtra
}

func NewInstance() (i *Instance) {
	i = &Instance{}
	return
}

func (i *Instance) IsEmpty() bool {
	if i == nil {
		return true
	}
	return nactor.IsPIDPtrEmpty(i.PID)
}

func (i Instance) String() string {
	ba, _ := json.Marshal(i)
	return string(ba)
}

func (i *Instance) Clone() (n *Instance) {
	if i == nil {
		return
	}
	n = &Instance{
		PID:          i.PID.Clone(),
		PprofAddress: i.PprofAddress,
	}
	if i.Extra != nil {
		n.Extra = i.Extra.Clone()
	}
	return
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
type Info struct {
	Config   nexport.IServiceConfig
	Instance *Instance
	Payload  int
}

func NewInfo(config nexport.IServiceConfig, id int) *Info {
	s := &Info{
		Config:  config,
		Payload: NilPayload,
	}
	s.Config.SetID(id)
	return s
}

func (i *Info) IsEmpty() bool {
	if i == nil {
		return true
	}
	return i.Config == nil
}

func (i *Info) Clone() (n *Info) {
	if i == nil {
		return
	}
	n = &Info{
		Config:   i.Config.Clone(),
		Instance: i.Instance.Clone(),
		Payload:  i.Payload,
	}
	return
}
